from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers
from .models import LayerGroup, LayerGroupMapping
from ..CanvasElementManagement.models import CanvasElement


# ==================== 图层组关联序列化器 ====================
class LayerGroupMappingSerializer(serializers.ModelSerializer):
    """关联关系基础序列化器"""
    group_name = serializers.CharField(source='group.name', read_only=True)
    element_name = serializers.CharField(source='element.name', read_only=True)
    text_content = serializers.CharField(source='element.text_element.text_content', read_only=True)
    image = serializers.SerializerMethodField()
    size = serializers.SerializerMethodField()
    position = serializers.SerializerMethodField()
    rotation = serializers.SerializerMethodField()
    opacity = serializers.SerializerMethodField()

    class Meta:
        model = LayerGroupMapping
        fields = [
            'group', 'group_name', 'element', 'element_name', 'image',
            'size', 'position', 'rotation', 'opacity', 'text_content'
        ]

    def get_image(self, obj):
        element = obj.element
        if not (element and element.type == 'mask'):
            return None

        mask_element = getattr(element, 'mask_element', None)
        if not (mask_element and mask_element.mask_type == 'image'):
            return None

        asset = getattr(mask_element, 'asset', None)
        return getattr(asset, 'url', None)

    def get_size(self, obj):
        """获取元素大小"""
        element = obj.element
        if not element:
            return None

        size = getattr(element, 'size', None)
        return size

    def get_position(self, obj):
        """获取元素位置"""
        element = obj.element
        if not element:
            return None

        position = getattr(element, 'position', None)
        return position

    def get_rotation(self, obj):
        """获取元素旋转角度"""
        element = obj.element
        if not element:
            return None

        rotation = getattr(element, 'rotation', None)
        return rotation

    def get_opacity(self, obj):
        """获取元素透明度"""
        element = obj.element
        if not element:
            return None

        opacity = getattr(element, 'opacity', None)
        return opacity


class CreateLayerGroupMappingSerializer(serializers.ModelSerializer):
    class Meta:
        model = LayerGroupMapping
        fields = ['group', 'element']


# ==================== 图层组序列化器 ====================
class LayerGroupSerializer(serializers.ModelSerializer):
    """图层组基础序列化器（用于详情和列表）"""
    mapping = serializers.SerializerMethodField()
    children = serializers.SerializerMethodField()

    class Meta:
        model = LayerGroup
        fields = [
            'id', 'canvas', 'name', 'visible', 'locked', 'z_index',
            'created_at', 'updated_at', 'mapping', 'parent', 'children',
        ]
        read_only_fields = ['created_at', 'updated_at']

    def validate_z_index(self, value):
        """验证z_index不能为负数"""
        if value is not None and value < 0:
            raise serializers.ValidationError("z_index不能为负数")
        return value

    def get_children(self, obj):
        """获取子组列表"""
        children = LayerGroup.objects.filter(parent=obj.id).order_by('z_index')
        return LayerGroupSerializer(children, many=True).data

    def get_mapping(self, obj):
        """获取组内元素列表"""
        mapping = obj.elements_mapping.select_related('element').first()
        return LayerGroupMappingSerializer(mapping).data


class CreateLayerGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = LayerGroup
        fields = ['canvas', 'name', 'visible', 'locked', 'parent']
        extra_kwargs = {
            'z_index': {'read_only': True},  # 禁止客户端设置
            'visible': {'default': True},
            'locked': {'default': False},
            'parent': {'required': False}
        }


class UpdateLayerGroupSerializer(serializers.ModelSerializer):
    children = serializers.ListField(
        child=serializers.DictField(),  # 递归处理子组
        required=False,
        write_only=True
    )

    class Meta:
        model = LayerGroup
        fields = [
            'id', 'name', 'visible', 'locked', 'z_index',
            'parent', 'children'
        ]
        extra_kwargs = {
            'z_index': {'read_only': True},
            'parent': {'read_only': True},
        }

    def update(self, instance, validated_data):
        # 处理嵌套子组更新
        children_data = validated_data.pop('children', [])

        # 更新当前组基础属性
        instance = super().update(instance, validated_data)

        # 递归处理子组更新
        for child_data in children_data:
            child_id = child_data.get('id')
            try:
                child_instance = LayerGroup.objects.get(id=child_id, parent=instance)
                child_serializer = UpdateLayerGroupSerializer(
                    instance=child_instance,
                    data=child_data,
                    partial=True
                )
                child_serializer.is_valid(raise_exception=True)
                child_serializer.save()
            except ObjectDoesNotExist:
                continue  # 或根据需求创建新子组

        return instance


# ==================== 嵌套序列化器（用于扩展查询） ====================
class NestedLayerGroupSerializer(LayerGroupSerializer):
    children = serializers.SerializerMethodField()

    class Meta(LayerGroupSerializer.Meta):
        fields = LayerGroupSerializer.Meta.fields + ['children']

    def get_children(self, obj):
        """获取嵌套子组结构"""
        return NestedLayerGroupSerializer(
            obj.children.all().order_by('z_index'),
            many=True
        ).data


class NestedCanvasElementSerializer(serializers.Serializer):
    """嵌套版元素序列化器（显示所属组信息）"""
    parent_groups = serializers.SerializerMethodField()

    def get_parent_groups(self, obj):
        """获取元素所属的所有组"""
        mappings = obj.parent_groups.all().order_by('group__z_index')
        return LayerGroupMappingSerializer(mappings, many=True).data
